package com.icss.flow.service.impl;


import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.gson.*;
import com.icss.flow.exception.CommonException;
import com.icss.flow.mapper.DynamicTableMapper;
import com.icss.flow.mapper.TMetaFieldMapper;
import com.icss.flow.pojo.entity.TMetaEntity;
import com.icss.flow.exception.FlowException;
import com.icss.flow.mapper.TMetaEntityMapper;
import com.icss.flow.pojo.dto.FlowDTO;
import com.icss.flow.pojo.dto.TMetaEntityDTO;
import com.icss.flow.pojo.dto.TMetaEntityPageDTO;
import com.icss.flow.pojo.entity.TMetaField;
import com.icss.flow.pojo.vo.EntityGroupVO;
import com.icss.flow.pojo.vo.TMetaEntityVO;
import com.icss.flow.pojo.vo.TMetaFieldVO;
import com.icss.flow.service.TMetaEntityService;

import com.icss.flow.service.TMetaFieldService;
import com.icss.flow.utils.MetaFieldUtils;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.dubbo.config.annotation.DubboReference;
import org.apache.dubbo.qos.command.exception.CommandException;
import org.camunda.bpm.engine.RepositoryService;
import org.camunda.bpm.engine.repository.ProcessDefinition;
import org.dromara.system.api.RemoteDictService;
import org.dromara.system.api.domain.vo.RemoteDictDataVo;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import java.util.*;


/**
 * 元数据实体表(TMetaEntity)表服务实现类
 *
 * @author makejava
 * @since 2024-01-30 12:42:00
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class TMetaEntityServiceImpl extends ServiceImpl<TMetaEntityMapper, TMetaEntity> implements TMetaEntityService {
    private static final String CLASS_NAME = "[TMeta Entity Service Impl] ";
    private final TMetaEntityMapper tMetaEntityMapper;

    private final RepositoryService repositoryService;

    private final DynamicTableMapper dynamicTableMapper;

    private final TMetaFieldMapper tMetaFieldMapper;
    private final TMetaFieldService tMetaFieldService;


    @DubboReference
    private final RemoteDictService remoteDictService;

    /**
     * 通过entityCode查询单条数据
     *
     * @return 实例对象
     */
    @Override
    public TMetaEntityDTO queryById(Integer entityCode) {
        TMetaEntity tMetaEntity = this.tMetaEntityMapper.queryById(entityCode);
        TMetaEntityDTO tMetaEntityDTO = new TMetaEntityDTO();
        BeanUtils.copyProperties(tMetaEntity, tMetaEntityDTO);
        return tMetaEntityDTO;
    }

    @Override
    public List<Integer> queryAllEntityCode() {
        return this.tMetaEntityMapper.queryAllEntityCode();
    }

    @Override
    public IPage<TMetaEntity> queryPage(TMetaEntityPageDTO pageDTO) {
        LambdaQueryWrapper<TMetaEntity> lbw = new LambdaQueryWrapper<>();
        if (StringUtils.isNotEmpty(pageDTO.getName())) {
            lbw.like(TMetaEntity::getName, pageDTO.getName());
        }
        if (StringUtils.isNotEmpty(pageDTO.getLabel())) {
            lbw.like(TMetaEntity::getLabel, pageDTO.getLabel());
        }

        IPage<TMetaEntity> page = this.page(new Page<>(pageDTO.getPageNo(), pageDTO.getPageSize()), lbw);
        return page;
    }



    /**
     * 分组查询-实体列表
     *
     * @return 分页数据Page
     */
    @Override
    public List<EntityGroupVO> queryListAndGroup(TMetaEntityPageDTO pageDTO) {
        LambdaQueryWrapper<TMetaEntity> lqw = new LambdaQueryWrapper<>();
        if(StringUtils.isNotEmpty(pageDTO.getName())){
            lqw.like(TMetaEntity::getName, pageDTO.getName());
        }
        if(StringUtils.isNotEmpty(pageDTO.getLabel())){
            lqw.like(TMetaEntity::getName, pageDTO.getLabel());
        }
        //条件查询所有实体
        List<TMetaEntity> tMetaEntityList = tMetaEntityMapper.selectList(lqw);
        //查询字典 获取所有实体标签
        List<String> sysEntityTags = remoteDictService.selectDictDataByType("sys_entity_tags").stream().map(RemoteDictDataVo::getDictLabel).toList();
        List<EntityGroupVO> groupList = new ArrayList<EntityGroupVO>();
        // 根据 tags 列表对数据进行分组
        sysEntityTags.forEach(tag -> {
            List<TMetaEntity> group = tMetaEntityList.stream()
                    .filter(data -> Objects.nonNull(data.getTags()) && Arrays.asList(data.getTags().split(",")).contains(tag))
                    .toList();
            List<TMetaEntityVO> tMetaEntityVOList = BeanUtil.copyToList(group, TMetaEntityVO.class);
            EntityGroupVO groupVO = new EntityGroupVO(tag,tMetaEntityVOList);
            groupList.add(groupVO);
        });
        //判断是否有 无标签的实体
        List<TMetaEntityVO> noGroupList = new ArrayList<>();
        tMetaEntityList.forEach(item -> {
            if (StringUtils.isEmpty(item.getTags())) {
                TMetaEntityVO tMetaEntityVO = BeanUtil.copyProperties(item, TMetaEntityVO.class);
                noGroupList.add(tMetaEntityVO);
            }
        });
        if (ObjectUtil.isNotEmpty(noGroupList)) {
            groupList.add(new EntityGroupVO("未分组",noGroupList));
        }
        return groupList;
    }
    /***
     * 新增元数据实体
     * @param tMetaEntityDTO
     * @return
     */
    @Override
    public Boolean createEntity(TMetaEntityDTO tMetaEntityDTO) {
        LambdaQueryWrapper<TMetaEntity> lqw = new LambdaQueryWrapper<>();
        lqw.eq(TMetaEntity::getName,tMetaEntityDTO.getName());
        List<TMetaEntity> tMetaEntityList = tMetaEntityMapper.selectList(lqw);
        if(CollectionUtil.isNotEmpty(tMetaEntityList)){
            throw new CommonException("当前实体已存在!");
        }
        TMetaEntity tMetaEntity = new TMetaEntity();
        BeanUtils.copyProperties(tMetaEntityDTO, tMetaEntity);
        tMetaEntity.setEntityId("0000001-" + UUID.randomUUID().toString().replace("-", ""));
        int maxEntityCode = tMetaEntityMapper.getMaxEntityCode();
        int entityCode = ++maxEntityCode;
        String tableName = "t_" + tMetaEntityDTO.getName();
        tMetaEntity.setPhysicalName(tableName);
        tMetaEntity.setEntityCode(entityCode);


        tMetaEntity.setDetailEntityFlag(0);
        tMetaEntity.setLayoutable(0);
        tMetaEntity.setListable(0);
        tMetaEntity.setAuthorizable(0);
        tMetaEntity.setShareable(0);
        tMetaEntity.setAssignable(0);


        //TODO 租户id设置
//        tMetaEntity.setTenantId(LoginHelper.getLoginUser().getTenantId());
        //保存实体数据
        this.save(tMetaEntity);
        String idName = tMetaEntityDTO.getName() + "Id";
        //保存实体默认字段
        tMetaFieldService.saveBatch(MetaFieldUtils.getDefualtFieldList(entityCode,idName));

        //构建表主键id
        String tableId = tMetaEntityDTO.getName() + "Id";
        //首次默认生成数据表 以及生成默认字段
        dynamicTableMapper.generateEntityTable(tableName, tableId, new ArrayList<>());
        return true;
    }


    @Override
    public boolean deleteEntity(Integer id) {
        return false;
    }


//    @Override
//    public void updateFlowKeyByEntityId(FlowDTO flowDTO) throws FlowException {
//        // 查询定义流程的实体
//        ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().deploymentId(flowDTO.getDeployId()).singleResult();
//        try {
//            // 根据实体id保存流程的key
//            int i = tMetaEntityMapper.updateFlowKeyByEntityId(flowDTO.getEntityId(), processDefinition.getKey());
//            if (i < 1) {
//                throw new FlowException();
//            }
//
//        } catch (Exception e) {
//            repositoryService.deleteDeployment(flowDTO.getDeployId());
//            log.warn("{}---->{}", CLASS_NAME, e.getMessage());
//            throw new FlowException("实体更新失败");
//        }
//    }

    /***
     * 查询实体详情
     * @return 实体vo
     */
    @Override
    public TMetaEntityVO getEntityDetail(Integer entityCode) {
        LambdaQueryWrapper<TMetaEntity> lqw = new LambdaQueryWrapper<>();
        lqw.eq(TMetaEntity::getEntityCode,entityCode);
        TMetaEntity tMetaEntity = this.getOne(lqw);
        if(ObjectUtil.isEmpty(tMetaEntity)){
            return null;
        }
        TMetaEntityVO tMetaEntityVO = BeanUtil.copyProperties(tMetaEntity, TMetaEntityVO.class);
        List<TMetaField> fieldList =  tMetaFieldMapper.selectList(new LambdaQueryWrapper<TMetaField>().eq(TMetaField::getEntityCode,entityCode));
        //过滤tenant_id字段
        tMetaEntityVO.setFieldList(BeanUtil.copyToList(fieldList, TMetaFieldVO.class));
        fieldList = fieldList.stream().filter(item -> !"tenant_id".equals(item.getName())).toList();
        tMetaEntityVO.setFieldList(BeanUtil.copyToList(fieldList, TMetaFieldVO.class));
        return tMetaEntityVO;
    }

    /**
     * 更新实体名称、分组tag
     * @param entityCode
     * @param label
     * @param tags
     * @return
     */
    @Override
    public Boolean updateEntity(Integer entityCode, String label, List<String> tags) {
        LambdaQueryWrapper<TMetaEntity> lqw = new LambdaQueryWrapper<>();
        lqw.eq(TMetaEntity::getEntityCode,entityCode);
        TMetaEntity tMetaEntity = this.getOne(lqw);
        if(StrUtil.isNotEmpty(label)){
            tMetaEntity.setLabel(label);
        }
        if(CollectionUtil.isNotEmpty(tags)){
            tMetaEntity.setTags(String.join(",",tags));
        }
        return this.updateById(tMetaEntity);
    }


    @Override
    public Boolean getEntityCode(Integer entityCode,String json) {
        TMetaEntity tMetaEntity = new TMetaEntity();
        Gson gson = new Gson();
        //  解析json
        JsonObject jsonObject = gson.fromJson(json, JsonObject.class);
        //  获取entityCode
        String jsonFormat = String.valueOf(jsonObject.get("json"));
        tMetaEntity.setEntityCode(entityCode);
        tMetaEntity.setEntityJson(jsonFormat);
        return this.update(tMetaEntity, new LambdaQueryWrapper<TMetaEntity>().eq(TMetaEntity::getEntityCode, entityCode));
    }


}
